<!-- <template>
    <div>
        <div id="container"></div>
        <div
            ref="marker"
            class="marker"
            v-show="markerVisible"
            :style="{ left: pixel.x + 26 + 'px', top: pixel.y - 16 + 'px' }"
        >
            <img
                :src="markerClose"
                alt=""
                class="marker_close"
                @click="compOverlayClose"
            />
            <div class="marker_header">
                <div>路口信息</div>
                <div>
                    <img :src="markerSxt" alt="" />
                    <img :src="markerSy" alt="" />
                </div>
            </div>
            <div class="marker_container">
                <div class="marker_container_item">
                    <div class="marker_container_item_title">所属位置</div>
                    <div class="marker_container_item_desc">
                        {{ markerRecord.name }}
                    </div>
                </div>
                <div class="marker_container_item">
                    <div class="marker_container_item_title">持续时间</div>
                    <div class="marker_container_item_desc">
                        {{ markerRecord.congestionDuration }}秒
                    </div>
                </div>
                <div class="marker_container_item">
                    <div class="marker_container_item_title">拥堵长度</div>
                    <div class="marker_container_item_desc">
                        {{ markerRecord.congestion }}米
                    </div>
                </div>
                <div class="marker_container_item">
                    <div class="marker_container_item_title">拥堵类型</div>
                    <div class="marker_container_item_desc">
                        {{
                            markerRecord.congestionType === 1 ? "常发" : "异常"
                        }}
                    </div>
                </div>
            </div>
        </div>
        <Left @zoomin="zoomoutFn" @zoomout="zoominFn" @traffic="trafficFn" />
        <Right />
        <Indicator />
    </div>
</template>

<script setup lang="ts">
import Left from "./components/Left.vue";
// import refreshScale from "@/scale";
import { onMounted, provide, ref } from "vue";
import yellowIcon from "@/assets/dashboard/icon_yellow@2x.png";
import warnIcon from "@/assets/dashboard/icon_warn@2x.png";
import dangerIcon from "@/assets/dashboard/icon_danger@2x.png";
import markerSxt from "@/assets/dashboard/marker_sxt@2x.png";
import markerSy from "@/assets/dashboard/marker_sy@2x.png";
import markerClose from "@/assets/dashboard/marker_close.png";
import markerLightImg from "@/assets/dashboard/icon_light@2x.png";
import {
    junctionCongestionList,
    lineStringIndexList,
} from "@/services/dashborad";
import dayjs from "dayjs";
import { CONGESTION, SEVERE_CONGESTION, SLOW_DOWN, OPEN } from "./constants";
import Indicator from "./components/Indicator.vue";
import { SYMBOL_MAP_TOOL_PROVIDER } from "@/const/symbol";
import { wgs84tobd09 } from "@/utils/map";

const map = ref<any>(null);
const createMap = () => {
    const map = new BMap.Map("container");
    const point = new BMap.Point(...wgs84tobd09(120.05762, 32.227029));
    map.centerAndZoom(point, 12);
    map.enableScrollWheelZoom(true);
    map.setMapStyleV2({
        styleId: "4e4376721b62bd7c018312fde9e2efaa",
    });
    return map;
};

const trafficFn = () => {
    traffic.value = !traffic.value;
    if (map.value) {
        getZoomMap();
    }
};

const traffic = ref<boolean>(true);
const zoominFn = () => {
    if (map.value) {
        map.value.zoomIn();
    }
};

const zoomoutFn = () => {
    if (map.value) {
        map.value.zoomOut();
    }
};

const createLable = ({
    point = [116.404, 39.915],
    offset = [0, 0],
    text,
    mapInstance,
}: any) => {
    const opts = {
        position: new BMap.Point(...point), // 指定文本标注所在的地理位置
        offset: new BMap.Size(...offset), // 设置文本偏移量
    };
    // 创建文本标注对象
    const label = new BMap.Label(text, opts);
    // 自定义文本标注样式

    label.setStyle({
        color: "#C0D9F2",
        borderRadius: "4px",
        borderColor: "#5286CE",
        backgroundColor: "rgba(8,27,53,0.85)",
        padding: "6px",
        fontSize: "14px",
        height: "30px",
        lineHeight: "14px",
        fontFamily: "微软雅黑",
    });
    mapInstance?.addOverlay?.(label);
    return label;
};
const marker = ref<any>(null);
const markerVisible = ref<boolean>(false);
const pixel = ref<any>({ x: 0, y: 0 });
const compOverlay = ref<any>(null);
const markerRecord = ref<any>({});
const compOverlayClose = () => {
    markerVisible.value = false;
    map.value.removeOverlay(compOverlay.value);
};
const createDOM = ({ point, record }: any) => {
    // 创建自定义覆盖物
    function ComplexCustomOverlay() {}
    ComplexCustomOverlay.prototype = new BMap.Overlay();
    ComplexCustomOverlay.prototype.initialize = function () {
        markerRecord.value = record;
        this._div = marker.value;
        this._div.onmouseover = function () {};
        this._div.onmouseout = function () {};
        map.value.getPanes().labelPane.appendChild(this._div);
        return this._div;
    };
    ComplexCustomOverlay.prototype.draw = function () {
        pixel.value = map.value.pointToOverlayPixel(point);
    };
    markerVisible.value = true;
    const myCompOverlay: any = new (ComplexCustomOverlay as any)();
    map.value.addOverlay(myCompOverlay);
    compOverlay.value = myCompOverlay;
    return myCompOverlay;
};

const points = ref<any>([]);
const alarmPoints = ref<any>([]);
const createAlarmIcon = ({
    point,
    type,
    mapInstance,
    offsetSize = [0, -35],
}: any) => {
    // 创建Marker标注，使用小车图标
    const pt = point;
    let iconImg = yellowIcon;
    let marker = null;
    const iconSize = [40, 42];
    if (type === SLOW_DOWN) {
        iconImg = yellowIcon;
        const icon = new BMap.Icon(iconImg, new BMap.Size(...iconSize));
        icon.setImageSize(new BMap.Size(...iconSize));
        marker = new BMap.Marker(pt, {
            icon,
        });
        marker.setOffset(new BMap.Size(...offsetSize));
    }
    if (type === CONGESTION) {
        iconImg = warnIcon;
        const icon = new BMap.Icon(iconImg, new BMap.Size(...iconSize));
        icon.setImageSize(new BMap.Size(...iconSize));
        marker = new BMap.Marker(pt, {
            icon,
            offset: new BMap.Size(...offsetSize),
        });
    }
    if (type === SEVERE_CONGESTION) {
        iconImg = dangerIcon;
        const icon = new BMap.Icon(iconImg, new BMap.Size(...iconSize));
        icon.setImageSize(new BMap.Size(...iconSize));
        marker = new BMap.Marker(pt, {
            icon,
        });
        marker.setOffset(new BMap.Size(...offsetSize));
    }
    // 将标注添加到地图
    if (marker) {
        marker.addEventListener("click", function () {
            map.value.centerAndZoom(pt, 15);
        });
        alarmPoints.value.push(marker);
        mapInstance?.addOverlay?.(marker);
    }
};
const createIcon = ({ point = [], type, mapInstance, record }: any) => {
    //  1 畅通，2 缓行，3 拥堵，4严重拥堵
    const markerLightIcon = new BMap.Icon(
        markerLightImg,
        new BMap.Size(10, 30)
    );
    markerLightIcon.setImageSize(new BMap.Size(10, 30));
    // 创建Marker标注，使用小车图标
    const pt = new BMap.Point(...point);

    const markerLight = new BMap.Marker(pt, {
        icon: markerLightIcon,
    });
    markerLight.setZIndex(1000);
    markerLight.addEventListener("mouseover", function () {
        if (markerLight.label) {
            markerLight.label.show();
        } else {
            markerLight.label = createLable({
                point,
                text: record.name,
                offset: [10, -30],
                mapInstance: map.value,
            });
        }
    });
    markerLight.addEventListener("mouseout", function () {
        markerLight.label.hide();
    });
    markerLight.addEventListener("click", function () {
        createDOM({
            point: pt,
            record,
        });
    });
    createAlarmIcon({ point: pt, type, mapInstance, record });
    points.value.push(markerLight);
    mapInstance?.addOverlay?.(markerLight);
};
const junctionCongestionListData = ref<any[]>([]);
const locations = ref<any[]>([]);
const getJunctionCongestionList = async () => {
    const data: any[] = await junctionCongestionList({
        currentTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
    });

    junctionCongestionListData.value = data || [];
    locations.value = junctionCongestionListData.value.map((item: any) => {
        createIcon({
            point: item.location,
            type: item.congestionLevel,
            mapInstance: map.value,
            record: item,
        });
        return item.location;
    });
    return data;
};

const lineStringIndexListData = ref<any[]>([]);
const getLineStringIndexList = async (params: any) => {
    const data: any = await lineStringIndexList({
        currentTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
        ...params,
    });
    lineStringIndexListData.value = data || [];
    return data;
};
const initMap: any = () => {
    map.value = createMap();
};

provide(SYMBOL_MAP_TOOL_PROVIDER, {
    setCenter(point: [number, number]) {
        if (point?.length === 2) {
            map.value?.setCenter?.(new BMap.Point(...point));
        }
    },
});

const lineMap: any = {};
const hideLine = (list: any[]) => {
    list.forEach((index) => {
        lineMap[`line${index}Layer`]?.hide?.();
        // lineMap[`line${index}Layer`]?.getVisible();
    });
};
const showLine = (list: any[]) => {
    list.forEach((index) => {
        lineMap[`line${index}Layer`]?.show?.();
        // lineMap[`line${index}Layer`]?.getVisible();
    });
};
const lineGeo = ({ coordinates, properties }: any) => {
    return {
        geometry: {
            coordinates,
            type: "LineString",
        },
        // type: "Feature",
        properties,
    };
};
const distanceAlarm = (start: any, end: any[], item: any) => {
    const distance = map.value.getDistance(start, end);
    if (distance > 500) {
        createAlarmIcon({
            point: start,
            type: item.congestionLevel,
            mapInstance: map.value,
            offsetSize: [0, 0],
        });
    }
};

const createLine = async (roadType: number) => {
    if (lineMap[`line${roadType}Layer`]) {
        return;
    }
    lineMap[`line${roadType}Layer`] = {};
    const lineStringIndexListData = await getLineStringIndexList({
        roadType,
    });
    const lineStringData: any[] = [];

    lineStringIndexListData.forEach((item: any) => {
        if (item.congestionLevel === OPEN) {
            const line = lineGeo({
                coordinates: item.lineString,
                properties: { congestionLevel: OPEN },
            });
            lineStringData.push(line);
        } else if (item.congestionLevel === SLOW_DOWN) {
            const line = lineGeo({
                coordinates: item.lineString,
                properties: { congestionLevel: SLOW_DOWN },
            });
            lineStringData.push(line);
            distanceAlarm(
                new BMap.Point(...item.lineString[0]),
                alarmPoints.value?.at?.(-1)?.getPosition?.(),
                item
            );
        } else if (item.congestionLevel === CONGESTION) {
            const line = lineGeo({
                coordinates: item.lineString,
                properties: { congestionLevel: CONGESTION },
            });
            lineStringData.push(line);
            distanceAlarm(
                new BMap.Point(...item.lineString[0]),
                alarmPoints.value?.at?.(-1)?.getPosition?.(),
                item
            );
        } else if (item.congestionLevel === SEVERE_CONGESTION) {
            const line = lineGeo({
                coordinates: item.lineString,
                properties: { congestionLevel: SEVERE_CONGESTION },
            });
            lineStringData.push(line);

            distanceAlarm(
                new BMap.Point(...item.lineString[0]),
                alarmPoints.value?.at?.(-1).getPosition(),
                item
            );
        }
    });

    // const lineLayer = new BMap.LineLayer({
    //     style: {
    //         borderColor: [
    //             "case",
    //             ["boolean", ["feature-state", "picked"], false],
    //             "rgba(10, 245, 180, 0.3)",
    //             [
    //                 "match",
    //                 ["get", "congestionLevel"],
    //                 OPEN,
    //                 "rgba(10, 245, 180, 0.3)",
    //                 SLOW_DOWN,
    //                 "rgba(255, 156, 73, 0.3)",
    //                 CONGESTION,
    //                 "rgba(255, 96, 107, 0.3)",
    //                 SEVERE_CONGESTION,
    //                 "rgba(242, 0, 48, 0.3)",
    //                 "rgba(10, 245, 180, 0.3)",
    //             ],
    //         ],
    //         strokeLineJoin: "round",
    //         borderWeight: 2,
    //         strokeWeight: 2,
    //         strokeColor: [
    //             "case",
    //             ["boolean", ["feature-state", "picked"], false],
    //             "rgba(10, 245, 180, 1)",
    //             [
    //                 "match",
    //                 ["get", "congestionLevel"],
    //                 OPEN,
    //                 "rgba(10, 245, 180, 1)",
    //                 SLOW_DOWN,
    //                 "rgba(255, 156, 73, 1)",
    //                 CONGESTION,
    //                 "rgba(255, 96, 107, 1)",
    //                 SEVERE_CONGESTION,
    //                 "rgba(242, 0, 48, 1)",
    //                 "rgba(10, 245, 180, 1)",
    //             ],
    //         ],
    //     },
    // });

    // const lineData = {
    //     type: "FeatureCollection",
    //     features: lineStringData,
    // };
    // lineLayer.setData(lineData);
    var dataSet = new mapv.DataSet(lineStringData);
    var options = {
        strokeStyle: "rgba(10, 245, 180, 1)",
        shadowColor: "rgba(10, 245, 180, 0.6)",
        shadowBlur: 20,
        shadowOffsetX: 0,
        lineWidth: 4.0,
        // draw: "simple",
    };

    var lineLayer = new mapv.baiduMapLayer(map.value, dataSet, options);
    lineMap[`line${roadType}Layer`] = lineLayer;

    // map.value.addNormalLayer(lineLayer);
};
const getZoomMap = () => {
    const zoom: number = map.value.getZoom();
    if (zoom < 8) {
        if (traffic.value) {
            showLine([2]);
            hideLine([3, 4, 5]);
        } else {
            hideLine([2, 3, 4, 5]);
        }
        createLine(2);
    } else if (zoom >= 8 && zoom < 13) {
        if (traffic.value) {
            showLine([2, 3]);
            hideLine([4, 5]);
        } else {
            hideLine([2, 3, 4, 5]);
        }
        createLine(2);
        createLine(3);
    } else if (zoom >= 13 && zoom < 15) {
        if (traffic.value) {
            showLine([2, 3, 4]);
            hideLine([5]);
        } else {
            hideLine([2, 3, 4, 5]);
        }
        createLine(2);
        createLine(3);
        createLine(4);
    } else if (zoom >= 15) {
        if (traffic.value) {
            showLine([2, 3, 4, 5]);
        } else {
            hideLine([2, 3, 4, 5]);
        }

        createLine(2);
        createLine(3);
        createLine(4);
        createLine(5);
    }
    if (zoom >= 15) {
        points.value.forEach((item: any) => {
            item.show();
        });
    } else {
        points.value.forEach((item: any) => {
            item.hide();
        });
    }
};
onMounted(async () => {
    initMap();
    await getJunctionCongestionList();
    getZoomMap();
    map.value.addEventListener("zoomend", function () {
        // 获取缩放级别
        getZoomMap();
    });
});
</script>
<style lang="scss" scoped>
#container {
    height: 100vh;
}

.marker {
    position: absolute;
    background: url(@/assets/dashboard/marker_bg@2x.png) no-repeat center center /
        100% 100%;
    padding: 12px 14px 18px;
    width: 328px;
    height: 214px;
    box-sizing: border-box;
    .marker_close {
        position: absolute;
        width: 28px;
        height: 28px;
        top: -14px;
        right: -14px;
        cursor: pointer;
    }
    .marker_header {
        display: flex;
        justify-content: space-between;
        font-weight: 600;
        font-size: 16px;
        color: #ffffff;
        line-height: 24px;
        img {
            &:first-of-type {
                width: 80px;
            }
            &:nth-of-type(2) {
                width: 60px;
            }
            margin-left: 10px;
        }
    }
    .marker_container {
        margin-top: 10px;
        border: 1px solid #346694;
        .marker_container_item {
            display: flex;
            border-bottom: 1px solid #346694;
            &:last-of-type {
                border: none;
            }
            .marker_container_item_title {
                text-align: center;
                background: #113067;
                width: 84px;
                height: 34px;
                line-height: 34px;
                color: #c0d9f2;
                border-right: 1px solid #346694;
            }
            .marker_container_item_desc {
                padding-left: 14px;
                font-weight: 400;
                font-size: 14px;
                line-height: 34px;
                color: #c0d9f2;
                background: #041b40;
                flex: 1;
            }
        }
    }
}
</style> -->
